package org.mch.comm.db.exphandler;

import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

import org.mch.func.cons.ConsDB;
import org.mch.func.cons.ConsMCH;
import org.mch.func.entity.TableColumnEO;

/**
 * 描述：
 * 
 * @author MCH；Date：2008-10-01；<BR/>
 * 
 */
public class ExpRSJPABeanHandler extends ExpRSSQLHandler {
	private static final long serialVersionUID = 1L;

	public ExpRSJPABeanHandler(int dbmsType, String tableName) {
		super(dbmsType, tableName);
	}

	protected String buildClassName() {
		String tablecode = firstLetterUpperCase(toLowerCase(getTableName())) + "VO";
		String[] tmp = tablecode.split("_");
		if (tmp != null && tmp.length > 1) {
			StringBuffer tmpcode = new StringBuffer();
			for (int i = 0; i < tmp.length; i++) {
				if (i == 0) {
					tmpcode.append(tmp[i]);
				} else {
					tmpcode.append(firstLetterUpperCase(tmp[i]));
				}
			}
			return tmpcode.toString();
		}
		return tablecode;
	}

	public String getTablePKField() throws Exception {
		ResultSet rs = ConsDB.dbmd.getPrimaryKeys(null, null, getTableName());
		boolean temp = rs.next();
		if (temp) {
			return toLowerCase(rs.getString("COLUMN_NAME"));
		}
		return null;
	}

	public String handler(ResultSet rs) throws Exception {

		Map<String, TableColumnEO> types = getColmnTypes(getTableName());

		String str = this.handle(types);

		return str;
	}

	public String handle(Map<String, TableColumnEO> types) throws Exception {
		if (types == null) {
			return "";
		}
		String table_pk = getTablePKField();
		StringBuffer sb = new StringBuffer("");
		StringBuffer gs = new StringBuffer("");

		String[] fieldnames = (String[]) types.keySet().toArray(new String[0]);

		String tablecode = buildClassName();

		sb.append("\n\n");
		sb.append("import com.mchun.common.lang.*;\n");
		sb.append("import nc.vo.pub.SuperVO;\n\n");
		sb.append("");
		sb.append("import javax.persistence.Column;\n");
		sb.append("import javax.persistence.Entity;\n");
		sb.append("import javax.persistence.Id;\n");
		sb.append("import javax.persistence.Embedded;\n");
		sb.append("import javax.persistence.AttributeOverride;\n");
		sb.append("import javax.persistence.Table;\n\n");
		sb.append("");
		sb.append("\n");
		sb.append("import nc.vo.pub.lang.*;\n\n");
		sb.append("/**\n");
		sb.append(" * 实体类<BR>\n");
		sb.append(" * \n");
		sb.append(" * 对应表名：" + tablecode + ".java<BR>\n");
		sb.append(" * \n");
		sb.append(" * @author MC、ZL；Date：2008-05-01；<BR>\n");
		sb.append(" * \n");
		sb.append(" * 由MCHUtils工具生成；<BR>\n");
		sb.append(" * <BR>\n");
		sb.append(" */\n");
		sb.append("@Entity\n");
		sb.append("@Table(name = \"").append(getTableName()).append("\")\n");
		sb.append("public class ").append(tablecode).append(" extends SuperVO {\n");
		sb.append("\tprivate static final long serialVersionUID = 1L;\n\n");

		for (int i = 0; i < fieldnames.length; i++) {
			TableColumnEO colinfo = types.get(fieldnames[i]);
			String colname = fieldnames[i].toLowerCase();
			String coltypestr = byColTypeGetSuperVOJavaType(colinfo.coltype, colinfo.precision, colinfo.scale);

			sb.append("\t/**\n");
			sb.append("\t * " + colname + "��\n");
			sb.append("\t */\n");
			sb.append("");
			if (table_pk.equals(colname)) {
				sb.append("\t@Id\n");
			} else if (ConsMCH.LangSet.contains(coltypestr)) {
				sb.append("\t@Embedded\n");
				sb.append("\t@AttributeOverride(name = \"value\", column = @Column(name = \"" + colname + "\"))\n");
			} else {
				sb.append("\t@Column(name=\"" + colname + "\")\n");
			}
			sb.append("\tpublic ").append(coltypestr).append(" " + colname + ";\n\n");

			gs.append("\tpublic ");
			gs.append(coltypestr);
			gs.append(" get" + firstLetterUpperCase(colname) + "() {\n");
			gs.append("\t\treturn this." + colname + ";\n");
			gs.append("\t}\n\n");
			gs.append("\tpublic void set" + firstLetterUpperCase(colname) + "(").append(coltypestr)
					.append(" " + colname + ") {\n");
			gs.append("\t\tthis." + colname + " = " + colname + ";\n");
			gs.append("\t}\n\n");

			// buildSetMethodParaType(gs, coltypestr, colname);
		}

		sb.append(gs);

		sb.append("\tpublic String getPKFieldName() {\n");
		sb.append("\t\treturn \"" + table_pk + "\";\n");
		sb.append("\t}\n\n");

		sb.append("\tpublic String getTableName() {\n");
		sb.append("\t\treturn \"" + getTableName() + "\";\n");
		sb.append("\t}\n\n");

		sb.append("\tpublic String getPrimaryKey() {\n");
		sb.append("\t\treturn this." + table_pk + ";\n");
		sb.append("\t}\n\n");

		sb.append("\tpublic void setPrimaryKey(String pk) {\n");
		sb.append("\t\tthis." + table_pk + "=pk;\n");
		sb.append("\t}\n\n");

		sb.append("\tpublic String getParentPKFieldName() {\n");
		sb.append("\t\treturn null;\n");
		sb.append("\t}\n\n");

		sb.append("}\n\n\n");

		return sb.toString();
	}

	/**
	 * �õ��е�����
	 * 
	 * @throws Exception
	 */
	private Map<String, TableColumnEO> getColmnTypes(String table) throws Exception {
		Map<String, TableColumnEO> typeMap = new HashMap<String, TableColumnEO>();
		ResultSet rs = null;

		if (getDbmsType() == ConsDB.MSSQLServer2005)
			rs = ConsDB.dbmd.getColumns(null, null, table.toUpperCase(), "%");
		else if (getDbmsType() == ConsDB.PostgreSQL8) {
			rs = ConsDB.dbmd.getColumns(null, null, table.toLowerCase(), "%");
		} else {
			rs = ConsDB.dbmd.getColumns(null, getSchema(), table.toUpperCase(), "%");
		}

		while (rs.next()) {
			TableColumnEO colinfo = new TableColumnEO();
			colinfo.name = rs.getString("COLUMN_NAME").toUpperCase();
			colinfo.coltype = rs.getShort("DATA_TYPE");

			if (getDbmsType() == ConsDB.MSSQLServer2005) {
				colinfo.precision = rs.getInt("COLUMN_SIZE");
			} else {
				colinfo.precision = rs.getMetaData().getPrecision(4);
			}
			colinfo.scale = rs.getMetaData().getScale(1);
			typeMap.put(colinfo.name, colinfo);
		}

		return typeMap;
	}

	public String getSchema() {
		String strSche = null;
		try {
			String schema = ConsDB.dbmd.getUserName();
			switch (getDbmsType()) {
				case ConsDB.MSSQLServer2005:
					strSche = "dbo";
					break;
				case ConsDB.Oracle10g:
				case ConsDB.DB2: {
					if (schema == null || schema.length() == 0)
						throw new IllegalArgumentException("ORACLE");
					strSche = schema.toUpperCase();
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return strSche;
	}

	public String toUpperCase(String str) {
		return str.toUpperCase();
	}

	public String toLowerCase(String str) {
		return str.toLowerCase();
	}

	public String firstLetterUpperCase(String str) {
		return str.substring(0, 1).toUpperCase() + str.substring(1, str.length());
	}

}